# -*- coding: utf-8 -*-
"""
Web应用主模块
基于Flask的Web UI界面
"""

from flask import Flask, render_template, request, jsonify, send_file, redirect, url_for, flash
from flask_socketio import SocketIO, emit
import os
import uuid
import json
import subprocess
from pathlib import Path
import threading
import time
from datetime import datetime

# 获取项目根目录
project_root = Path(__file__).parent.parent.parent

# 核心模块导入（暂时注释，如果需要可以取消注释）
# from ...core.config import Config
# from ...core.pipeline import VideoPipeline
# from ...parsers.markdown_parser import MarkdownParser

# 创建Flask应用
app = Flask(__name__,
            template_folder='templates',
            static_folder='static')
app.config['SECRET_KEY'] = 'video_generation_web_ui_secret_key'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB max file size

# 初始化SocketIO
socketio = SocketIO(app, cors_allowed_origins="*")

# 全局配置
UPLOAD_FOLDER = Path(__file__).parent.parent.parent / "uploads"
OUTPUT_FOLDER = Path(__file__).parent.parent.parent / "outputs" / "web"
TEMPLATES_FOLDER = Path(__file__).parent / "templates"

UPLOAD_FOLDER.mkdir(parents=True, exist_ok=True)
OUTPUT_FOLDER.mkdir(parents=True, exist_ok=True)

# 任务存储
tasks = {}


@app.route('/')
def index():
    """首页"""
    return render_template('index.html')


@app.route('/api/config', methods=['GET'])
def get_config():
    """获取配置选项"""
    config_options = {
        'quality_levels': ['preview', 'standard', 'high', 'ultra'],
        'themes': ['dark', 'light', 'academic', 'presentation'],
        'resolutions': ['1280x720', '1920x1080', '2560x1440'],
        'fps_options': [24, 30, 60]
    }
    return jsonify(config_options)


@app.route('/api/upload', methods=['POST'])
def upload_file():
    """上传文件"""
    if 'file' not in request.files:
        return jsonify({'error': '没有文件'}), 400

    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': '没有选择文件'}), 400

    if file and file.filename.endswith('.md'):
        task_id = str(uuid.uuid4())
        filename = f"{task_id}_{file.filename}"
        filepath = UPLOAD_FOLDER / filename
        file.save(filepath)

        return jsonify({
            'task_id': task_id,
            'filename': file.filename,
            'path': str(filepath)
        })

    return jsonify({'error': '只支持Markdown文件'}), 400


@app.route('/api/generate', methods=['POST'])
def generate_video():
    """开始生成视频"""
    data = request.json

    task_id = data.get('task_id')
    if not task_id:
        return jsonify({'error': '缺少task_id'}), 400

    # 获取参数
    quality = data.get('quality', 'standard')
    theme = data.get('theme', 'dark')
    resolution = data.get('resolution', '1920x1080')
    fps = int(data.get('fps', 30))

    # 检查任务文件
    upload_files = list(UPLOAD_FOLDER.glob(f"{task_id}_*.md"))
    if not upload_files:
        return jsonify({'error': '文件不存在，请先上传'}), 400

    filepath = upload_files[0]

    # 创建任务
    task = {
        'id': task_id,
        'status': 'processing',
        'progress': 0,
        'start_time': datetime.now().isoformat(),
        'file': str(filepath),
        'config': {
            'quality': quality,
            'theme': theme,
            'resolution': resolution,
            'fps': fps
        },
        'output_path': str(OUTPUT_FOLDER / f"{task_id}.mp4"),
        'log': []
    }

    tasks[task_id] = task

    # 在后台线程中处理任务
    thread = threading.Thread(target=process_video, args=(task_id,))
    thread.daemon = True
    thread.start()

    return jsonify({'task_id': task_id, 'status': 'processing'})


def process_video(task_id):
    """处理视频生成的后台任务"""
    task = tasks.get(task_id)
    if not task:
        return

    try:
        # 获取上传的文件路径
        input_file = task['file']
        config = task['config']
        output_dir = Path(task['output_path']).parent

        # 更新进度
        task['status'] = 'processing'
        task['progress'] = 5
        task['current_step'] = '准备生成...'
        task['log'].append({
            'time': datetime.now().isoformat(),
            'message': '开始处理视频生成任务'
        })

        # 发送进度更新
        socketio.emit('progress', {
            'task_id': task_id,
            'progress': 5,
            'status': '准备生成...'
        })

        time.sleep(0.5)

        # 构建命令行参数
        cmd = [
            'python',
            str(project_root / 'markdown_to_video.py'),
            str(input_file),
            '--outdir', str(output_dir),
            '--no-manim',
            '--overwrite',
        ]

        # 添加配置参数
        if config.get('quality') in ['high', 'ultra']:
            cmd.extend(['--fps', str(config.get('fps', 30))])
            cmd.extend(['--resolution', config.get('resolution', '1920x1080')])

        if config.get('theme'):
            cmd.extend(['--theme', config.get('theme', 'dark')])

        if config.get('embed_subtitles'):
            cmd.append('--embed-subtitles')

        # 更新进度
        task['current_step'] = '执行视频生成...'
        task['progress'] = 10
        socketio.emit('progress', {
            'task_id': task_id,
            'progress': 10,
            'status': '执行视频生成...'
        })

        task['log'].append({
            'time': datetime.now().isoformat(),
            'message': f'执行命令: {" ".join(cmd)}'
        })

        # 执行命令
        process = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
            bufsize=1
        )

        # 实时读取输出
        total_output = ''
        for line in process.stdout:
            total_output += line
            line = line.strip()
            if line:
                # 更新日志
                task['log'].append({
                    'time': datetime.now().isoformat(),
                    'message': line
                })
                socketio.emit('progress', {
                    'task_id': task_id,
                    'progress': max(task['progress'], 50),
                    'status': line[:100]
                })

        # 等待进程完成
        return_code = process.wait()

        if return_code != 0:
            raise Exception(f'视频生成失败，返回码: {return_code}')

        # 查找生成的视频文件
        video_files = list(output_dir.glob('*.mp4'))
        if video_files:
            # 使用最新的视频文件
            video_file = max(video_files, key=lambda x: x.stat().st_mtime)
            task['output_path'] = str(video_file)
        else:
            raise Exception('未找到生成的视频文件')

        # 更新状态
        task['status'] = 'completed'
        task['progress'] = 100
        task['end_time'] = datetime.now().isoformat()
        task['log'].append({
            'time': datetime.now().isoformat(),
            'message': f'任务完成，输出文件: {task["output_path"]}'
        })

        # 发送完成通知
        socketio.emit('completed', {
            'task_id': task_id,
            'output_path': task['output_path']
        })

    except Exception as e:
        task['status'] = 'failed'
        task['error'] = str(e)
        task['log'].append({
            'time': datetime.now().isoformat(),
            'message': f'错误: {str(e)}',
            'level': 'error'
        })

        socketio.emit('error', {
            'task_id': task_id,
            'error': str(e)
        })


@socketio.on('connect')
def handle_connect():
    """客户端连接"""
    print('Client connected')


@socketio.on('disconnect')
def handle_disconnect():
    """客户端断开"""
    print('Client disconnected')


@socketio.on('check_status')
def handle_check_status(data):
    """检查任务状态"""
    task_id = data.get('task_id')
    task = tasks.get(task_id)

    if task:
        emit('status', {
            'task_id': task_id,
            'status': task['status'],
            'progress': task.get('progress', 0),
            'current_step': task.get('current_step', '')
        })


@app.route('/api/status/<task_id>')
def get_status(task_id):
    """获取任务状态"""
    task = tasks.get(task_id)

    if not task:
        return jsonify({'error': '任务不存在'}), 404

    return jsonify({
        'task_id': task_id,
        'status': task['status'],
        'progress': task.get('progress', 0),
        'current_step': task.get('current_step', ''),
        'log': task.get('log', [])
    })


@app.route('/api/tasks')
def list_tasks():
    """列出所有任务"""
    task_list = []
    for task_id, task in tasks.items():
        task_list.append({
            'task_id': task_id,
            'status': task['status'],
            'progress': task.get('progress', 0),
            'start_time': task.get('start_time'),
            'file': Path(task['file']).name if 'file' in task else ''
        })

    return jsonify({'tasks': task_list})


@app.route('/api/download/<task_id>')
def download_file(task_id):
    """下载生成的文件"""
    task = tasks.get(task_id)

    if not task:
        return jsonify({'error': '任务不存在'}), 404

    # 获取实际生成的视频文件路径
    output_path = Path(task['output_path'])

    # 如果output_path是目录，查找最新的视频文件
    if output_path.is_dir():
        video_files = list(output_path.glob('*.mp4'))
        if video_files:
            output_path = max(video_files, key=lambda x: x.stat().st_mtime)
        else:
            return jsonify({'error': '未找到视频文件'}), 404
    elif not output_path.exists():
        return jsonify({'error': '文件不存在'}), 404

    # 确保文件是视频文件
    if output_path.suffix.lower() != '.mp4':
        return jsonify({'error': '不支持的文件格式'}), 400

    # 生成下载文件名
    download_name = f"video_{task_id[:8]}.mp4"

    return send_file(
        output_path,
        as_attachment=True,
        download_name=download_name,
        mimetype='video/mp4'
    )


@app.route('/api/download-example/<path:example_id>')
def download_example_file(example_id):
    """下载示例Markdown文件"""
    # 映射表：将example_id映射到实际文件名
    example_mapping = {
        'basic-00': 'basic/00_basic_example.md',
        'basic-01': 'basic/01_simple_text.md',
        'basic-02': 'basic/02_code_example.md',
        'basic-03': 'basic/03_math_formulas.md',
        'intermediate-04': 'intermediate/04_multi_scene.md',
        'intermediate-05': 'intermediate/05_themed_video.md',
        'intermediate-06': 'intermediate/06_high_quality.md',
        'advanced-07': 'advanced/07_full_workflow.md',
        'advanced-08': 'advanced/08_checkpoint_resume.md',
        'advanced-09': 'advanced/09_batch_generation.md',
        'advanced-10': 'advanced/10_integration_test.md',
    }

    # 获取实际文件路径
    if example_id not in example_mapping:
        return jsonify({'error': f'未知的示例ID: {example_id}'}), 404

    example_path = project_root / 'examples' / example_mapping[example_id]

    if not example_path.exists():
        return jsonify({'error': f'示例文件不存在: {example_path}'}), 404

    return send_file(
        example_path,
        as_attachment=True,
        download_name=example_path.name,
        mimetype='text/markdown'
    )


@app.route('/examples')
def examples():
    """示例页面"""
    return render_template('examples.html')


@app.route('/about')
def about():
    """关于页面"""
    return render_template('about.html')


if __name__ == '__main__':
    # 开发模式
    socketio.run(app, debug=True, host='0.0.0.0', port=5000)
